﻿Imports PTIC_Util.GestionCalculs
Imports Actuariat
Imports OMANE.Common.Model.Parametrage

Namespace moteurTauxGaranti2

    ''' <summary>
    ''' La classe représentant une simulation individuelle (qui peut être composée de plusieurs paramètres)
    ''' </summary>
    ''' <remarks></remarks>
    Public Class SimulIndMoteur2
        Inherits CalculCompose

#Region "Variables de classe"
        Protected _temps1iterationEnS As Integer = 12
        Protected _moteur2 As Moteur_Methode2
        Protected WithEvents _lParametreSimulationIndividuelle As ParamSimulIndList
#End Region

#Region "Constructeur"
        ''' <summary>
        ''' 
        ''' </summary>
        ''' <remarks></remarks>
        Public Sub New(ByVal moteur2 As Moteur_Methode2, Optional ByVal addDefaut As Boolean = False)
            _moteur2 = moteur2
            _resultats = New DataTable
            _lParametreSimulationIndividuelle = New ParamSimulIndList
            'La simulation individuelle est dépendante du scénario central
            AjouteFonctionCalculIntermediaire(_moteur2.scenarioCentral)
            If addDefaut Then
                Dim paramSimulTx_Taxe As New ParamSimulInd(nomTx_TaxeAssu)
                paramSimulTx_Taxe.chocMin = 0
                paramSimulTx_Taxe.chocMax = 0
                paramSimulTx_Taxe.Pas = 0
                listeParametres.Add(paramSimulTx_Taxe)
            End If
        End Sub
#End Region

#Region "Propriété"
        ''' <summary>
        ''' 
        ''' </summary>
        ''' <remarks></remarks>
        Public ReadOnly Property listeParametres() As ParamSimulIndList
            Get
                Return _lParametreSimulationIndividuelle
            End Get
        End Property
        ''' <summary>
        ''' 
        ''' </summary>
        ''' <remarks></remarks>
        Public Overloads ReadOnly Property Resultats() As DataTable
            Get
                Return _resultats
            End Get
        End Property
#End Region

#Region "Gestion des paramètres de la simulation"
        ''' <summary>
        ''' 
        ''' </summary>
        ''' <remarks></remarks>
        Public Sub onAjoutParametre(ByVal sender As Object, ByVal e As ParamSimulIndListEventArgs) Handles _lParametreSimulationIndividuelle.afterAdd
            Dim param As ParamSimulInd = e.Parametre
            Me.Invalider()
            MAJEstimationDuree()
            AddHandler param.NbIterations_HasChanged, AddressOf onNbIterations_changed
            AddHandler param.ChocMax_HasChanged, AddressOf onChocMax_hasChanged
            AddHandler param.ChocMin_HasChanged, AddressOf onChocMin_hasChanged
            AddHandler param.Pas_HasChanged, AddressOf onPas_HasChanged
        End Sub
        ''' <summary>
        ''' 
        ''' </summary>
        ''' <remarks></remarks>
        Public Sub onRetraitParametre(ByVal sender As Object, ByVal e As ParamSimulIndListEventArgs) Handles _lParametreSimulationIndividuelle.afterRemove
            Dim param As ParamSimulInd = e.Parametre
            Me.Invalider()
            MAJEstimationDuree()
            RemoveHandler param.NbIterations_HasChanged, AddressOf onNbIterations_changed
            RemoveHandler param.ChocMax_HasChanged, AddressOf onChocMax_hasChanged
            RemoveHandler param.ChocMin_HasChanged, AddressOf onChocMin_hasChanged
            RemoveHandler param.Pas_HasChanged, AddressOf onPas_HasChanged
        End Sub
        ''' <summary>
        ''' 
        ''' </summary>
        ''' <remarks></remarks>
        Public Sub onNbIterations_changed(ByVal sender As Object, ByVal e As paramSimulIndNbIterationsEventArgs)
            MAJEstimationDuree()
        End Sub
        ''' <summary>
        ''' 
        ''' </summary>
        ''' <remarks></remarks>
        Public Sub onChocMin_hasChanged(ByVal sender As Object, ByVal e As paramSimulIndInfoChocEventArgs)
            Me.Invalider()
        End Sub
        ''' <summary>
        ''' 
        ''' </summary>
        ''' <remarks></remarks>
        Public Sub onChocMax_hasChanged(ByVal sender As Object, ByVal e As paramSimulIndInfoChocEventArgs)
            Me.Invalider()
        End Sub
        ''' <summary>
        ''' 
        ''' </summary>
        ''' <remarks></remarks>
        Public Sub onPas_HasChanged(ByVal sender As Object, ByVal e As paramSimulIndInfoChocEventArgs)
            Me.Invalider()
        End Sub
#End Region

#Region "Procédure de calcul de la simulation"
        ''' <summary>
        ''' 
        ''' </summary>
        ''' <remarks></remarks>
        Protected Overrides Sub ProcedureCalcul()
            _resultats = New DataTable
            _moteur2.TypeScenarioCalcule = Moteur_Methode2.TypeCalcul.Simulations
            For Each paramSimul As ParamSimulInd In _lParametreSimulationIndividuelle
                Resultats.Columns.Add(paramSimul.Nom, GetType(Double))
            Next
            Resultats.Columns.Add("TRI", GetType(Double))
            Resultats.Columns.Add("VAN", GetType(Double))
            Resultats.Rows.Add(Resultats.NewRow)

            _moteur2.CalculeInit()
            calculeLigneEnCours(Resultats, _lParametreSimulationIndividuelle, 0)
            Resultats.Rows.RemoveAt(Resultats.Rows.Count - 1)
            'Réinitialiser tous les simulDble
            For Each paramSimul As ParamSimulInd In _lParametreSimulationIndividuelle
                _moteur2.listeParametres.Item(paramSimul.Nom).SimulDouble = 0
            Next

            _moteur2.CalculeCloture()
            _moteur2.TypeScenarioCalcule = Moteur_Methode2.TypeCalcul.ScenarioCentral
        End Sub
        ''' <summary>
        ''' 
        ''' </summary>
        ''' <remarks></remarks>
        Private Sub calculeLigneEnCours(ByRef res As DataTable, _
                                        ByVal listParametres As ParamSimulIndList, _
                                        ByVal indexParam As Integer)

            If indexParam <= listeParametres.Count - 1 Then
                Dim param As ParamSimulInd = listParametres(indexParam)
                For i As Double = param.chocMin To param.chocMax Step param.Pas
                    _moteur2.listeParametres.Item(param.Nom).SimulDouble = i
                    calculeLigneEnCours(res, listeParametres, indexParam + 1)
                Next

            Else
                _moteur2.invalideAll()
                _moteur2.Calculer()
                For Each c As DataColumn In res.Columns
                    If _moteur2.listeParametres.Keys.Contains(c.ColumnName) Then
                        res.Rows(res.Rows.Count - 1)(c.ColumnName) = _moteur2.listeParametres.Item(c.ColumnName).SimulDouble
                    End If
                Next
                res.Rows(res.Rows.Count - 1)("TRI") = _moteur2.Resultats.compteIndicateur.TRI
                res.Rows(res.Rows.Count - 1)("VAN") = _moteur2.Resultats.compteIndicateur.VAN
                res.Rows.Add(res.NewRow)

            End If

        End Sub
        ''' <summary>
        ''' 
        ''' </summary>
        ''' <remarks></remarks>
        Protected Sub MAJEstimationDuree()
            Dim estimationDureeCalcul As TimeSpan = New TimeSpan(0)
            Dim calculNbIterations As Integer = 0
            For Each paramSimulInd As ParamSimulInd In _lParametreSimulationIndividuelle
                If calculNbIterations = 0 Then
                    calculNbIterations = calculNbIterations + paramSimulInd.NbIterations
                Else
                    calculNbIterations = calculNbIterations * paramSimulInd.NbIterations
                End If
            Next
            _tempsCalcul = System.TimeSpan.FromSeconds(_temps1iterationEnS * calculNbIterations)
            NotifyPropertyChanged("TempsCalcul")
        End Sub
#End Region

    End Class

End Namespace